/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package uit.tkorg.coauthorgraph.utility;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Hashtable;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Element;
import org.dom4j.Document;
import uit.tkorg.coauthorgraph.dto.CrawlAuthorDTO;
import uit.tkorg.coauthorgraph.property.file.MASearchCrawlPatterns;

/**
 *
 * @author Tin, Tien, Cuong
 */
public class MASFetcher {
	
    /**
     * submit query to MAS to get the HTML content of returned page
     * @param authorName
     * @return
     */
    public String fetchHTMLContentForAuthor(String authorName) {
        String htmlContent = null;
        try {
            authorName = URLEncoder.encode(authorName, "utf-8").replace("+", "%20");
            String _urlString = MASearchCrawlPatterns.URL_START + authorName + MASearchCrawlPatterns.DOMAIN_COMPUTER_SCIENCE;
            URL urlSubmit = new URL(_urlString);
            System.out.println(urlSubmit.toString());
            htmlContent = CommonURLQuery.getHTMLPageContent(urlSubmit);
        }
        catch (Exception ex) {
            ex.printStackTrace();
        }
        return htmlContent;
    }
	
    /**
     * get the author name from URL link to the specified author
     * @param url
     * @return
     */
    public static String getAuthorNameFromURL (String url){
        String authorName = null;
        url = url.replace(MASearchCrawlPatterns.URL_WITH_AUTHOR_ID, "");
        int lastCharacterIndex = url.indexOf("/");
        authorName = url.substring(lastCharacterIndex + 1, url.length());
        return authorName;
    }

    /**
     * Get the link of an suggested author
     * @param strContent:
     * @return: suggestedAuthor
     */
    public static String getSuggestedAuthorLink(String strContent){
        String authorLink = "";
        org.jsoup.nodes.Document doc = Jsoup.parse(strContent);
        Element link = doc.select(MASearchCrawlPatterns.A).first();
        authorLink = link.attr(MASearchCrawlPatterns.HREF);
        return authorLink;
    }

    public static String getSuggestedAuthorName(String strContent) {
        String authorName = "";
        org.jsoup.nodes.Document doc = Jsoup.parse(strContent);
        Element link = doc.select(MASearchCrawlPatterns.A).first();
        authorName = link.text();
        return authorName;
    }

    /**
     * get the suggested authors
     * @param _pageContent
     * @return
     */
    public static ArrayList getSuggestedAuthors(String pageContent){
        CrawlAuthorDTO crawlAuthorDTO;

        ArrayList suggestedAuthors = new ArrayList();
        String subString  = MASearchCrawlPatterns.CLASS_AUTHORS;
        ArrayList lstAuthorNameIndex = CommonStringUtility.getListIndexOfSubStringInString(pageContent, subString);
        String authorLink = "";
        String authorName = "";
        for(int i= 0; i < lstAuthorNameIndex.size() - 1; i++){
            authorLink = getSuggestedAuthorLink(pageContent.substring(((Integer)lstAuthorNameIndex.get(i)).intValue(),
                                                    ((Integer)lstAuthorNameIndex.get(i+1)).intValue()));
            authorName = getSuggestedAuthorName(pageContent.substring(((Integer)lstAuthorNameIndex.get(i)).intValue(),
                                                    ((Integer)lstAuthorNameIndex.get(i+1)).intValue()));
            crawlAuthorDTO = new CrawlAuthorDTO();
            crawlAuthorDTO.setAuthorName(authorName);
            crawlAuthorDTO.setUrl(MASearchCrawlPatterns.ACCADEMIC_HOMEPAGE_URL + authorLink);
            suggestedAuthors.add(crawlAuthorDTO);
        }

        if(lstAuthorNameIndex.size() > 0) {
            authorLink = getSuggestedAuthorLink(pageContent.substring(((Integer)lstAuthorNameIndex.get(lstAuthorNameIndex.size() - 1)).intValue()));
            authorName = getSuggestedAuthorName(pageContent.substring(((Integer)lstAuthorNameIndex.get(lstAuthorNameIndex.size() - 1)).intValue()));
            crawlAuthorDTO = new CrawlAuthorDTO();
            crawlAuthorDTO.setAuthorName(authorName);
            crawlAuthorDTO.setUrl(MASearchCrawlPatterns.ACCADEMIC_HOMEPAGE_URL + authorLink);
            suggestedAuthors.add(crawlAuthorDTO);
        }
                
        return suggestedAuthors;
    }

    /**
     *
     * @param link
     * @return
     */
    public static String getAuthorPageDetail(String link){
        URL _url;
        String _result = "";
        try {
            _url = new URL(link);
            _result = CommonURLQuery.getHTMLPageContent(_url);
        } catch (MalformedURLException e) {
            System.out.println("Link khong hop le!");
        } catch (IOException e) {
            System.out.println("Link khong hop le!");
        }

        return _result;
    }

    /**
     * To get list name of conferences with ID of Author
     * @param authorId
     * @param numCon
     * @return
     */
    public static Hashtable getConferenceFromAuthorID(int authorId, int numCon) {
        Hashtable conferences = new Hashtable();
        int start = 1;
        int end = MASearchCrawlPatterns.MAX_NUMBER_SHOW_IN_PAGE;
        int numConPerPage = MASearchCrawlPatterns.MAX_NUMBER_SHOW_IN_PAGE;
        int numPage = (numCon) / numConPerPage;

        for (int i = 0; i <= numPage; i++) {
            int MaxRunPerPage = numConPerPage;
            if (i == numPage) {
                MaxRunPerPage = numCon - numConPerPage * numPage;
            }
            try {
                String htmlContent = CommonURLQuery.getHTMLPageContent(new URL(
                                MASearchCrawlPatterns.ACCADEMIC_CONFERENCE_QUERY
                                                + authorId + MASearchCrawlPatterns.AND
                                                + MASearchCrawlPatterns.START + "=" + start
                                                + MASearchCrawlPatterns.AND
                                                + MASearchCrawlPatterns.END + "=" + end));
                for (int j = 0; j < MaxRunPerPage; j++) {
                    // try getting conference name from pattern tag id
                    String conNum = String.valueOf(j);
                    if (j < 10) {
                        conNum = "0" + conNum;
                    }
                    String confName = CommonHTMLProcessor.getTextOfDivTag(htmlContent,
                                                    MASearchCrawlPatterns.CONFERENCE_AND_JOURNAL_AND_KEYWORD_PATTERN_DIV
                                                                    .replaceAll("\\(NUM\\)", conNum));
                    String confPubNum = CommonHTMLProcessor.getTextOfDivTag(htmlContent,
                                                    MASearchCrawlPatterns.CONFERENCE_PUBLICATION_NUMBER_DIV
                                                                    .replaceAll("\\(NUM\\)", conNum));
                    confPubNum = confPubNum.substring(0, confPubNum.indexOf(" "));
                    conferences.put(confName, confPubNum);
                }
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            start = start + numConPerPage;
            end = end + numConPerPage;
        }
        return conferences;
    }

    /**
     * To get list name of coAuthor with ID of Author
     * @param authorId
     * @param numCo
     * @return
     */
    public static Hashtable getCoAuthorFromAuthorID(int authorId,int numCo) {
        Hashtable coAuthors = new Hashtable();

        int start = 1;
        int end = MASearchCrawlPatterns.MAX_NUMBER_SHOW_IN_PAGE;
        int numAuthorPerPage = MASearchCrawlPatterns.MAX_NUMBER_SHOW_IN_PAGE;
        int numPage = (numCo) /numAuthorPerPage ;

        for (int i = 0; i <= numPage; i++) {
            int MaxCoAuthorPerCurrentPage = numAuthorPerPage;
            if(i==numPage){
                MaxCoAuthorPerCurrentPage = numCo-numAuthorPerPage*numPage;
            }
            try {
                String htmlContent = CommonURLQuery.getHTMLPageContent(new URL(
                                        MASearchCrawlPatterns.ACCADEMIC_COAUTHOR_QUERY + authorId +
                                        MASearchCrawlPatterns.AND+
                                        MASearchCrawlPatterns.START + "=" +start +
                                        MASearchCrawlPatterns.AND+
                                        MASearchCrawlPatterns.END + "=" + end));
                for (int j = 0; j < MaxCoAuthorPerCurrentPage; j++) {
                    // try getting co-author name from pattern tag id
                    String auNum = String.valueOf(j);
                    if (j < 10) {
                        auNum = "0" + auNum;
                    }

                    String coAuthorName = CommonHTMLProcessor.getTextOfDivTag(htmlContent,
                                                MASearchCrawlPatterns.COAUTHOR_PATTERN_DIV.replaceAll("\\(NUM\\)",auNum));
                    String coAuthorPublicationNum = CommonHTMLProcessor.getTextOfDivTag(htmlContent,
                                                MASearchCrawlPatterns.COAUTHOR_PUBLICATION_NUMBER_DIV.replaceAll("\\(NUM\\)",auNum));
                    coAuthorPublicationNum = coAuthorPublicationNum.substring(0, coAuthorPublicationNum.indexOf(" "));
                    coAuthors.put(coAuthorName, coAuthorPublicationNum);
                }
            } catch (MalformedURLException e) {
                    e.printStackTrace();
            } catch (IOException e) {
                    e.printStackTrace();
            }
            start = start + numAuthorPerPage;
            end = end + numAuthorPerPage;
        }
        return coAuthors;
    }

    /**
     *
     * @param authorId : Author ID
     * @param numJour : Number of Journal
     * @return list Journal
     */
    public static Hashtable getJournalFromAuthorID(int authorId, int numJour) {
        Hashtable journals = new Hashtable();
        int start = 1;
        int end = MASearchCrawlPatterns.MAX_NUMBER_SHOW_IN_PAGE;
        int numJourPerPage = MASearchCrawlPatterns.MAX_NUMBER_SHOW_IN_PAGE;
        int numPage = (numJour) / numJourPerPage;
        for (int i = 0; i <= numPage; i++) {
            int MaxRunPerPage = numJourPerPage;
            if (i == numPage) {
                MaxRunPerPage = numJour - numJourPerPage * numPage;
            }
            try {
                String htmlContent = CommonURLQuery.getHTMLPageContent(new URL(
                                                MASearchCrawlPatterns.ACCADEMIC_JOURNAL_QUERY + authorId
                                                + MASearchCrawlPatterns.AND
                                                + MASearchCrawlPatterns.START + "=" + start
                                                + MASearchCrawlPatterns.AND
                                                + MASearchCrawlPatterns.END + "=" + end));
                for (int j = 0; j < MaxRunPerPage; j++) {
                    // try getting journal name from pattern tag id
                    String conNum = String.valueOf(j);
                    if (j < 10) {
                        conNum = "0" + conNum;
                    }
                    String jourName = CommonHTMLProcessor.getTextOfDivTag(htmlContent,
                                                    MASearchCrawlPatterns.CONFERENCE_AND_JOURNAL_AND_KEYWORD_PATTERN_DIV
                                                                    .replaceAll("\\(NUM\\)", conNum));
                    String jourPubNum = CommonHTMLProcessor.getTextOfDivTag(htmlContent,
                                                    MASearchCrawlPatterns.JOURNAL_PUBBLICATION_NUMBER_DIV
                                                                    .replaceAll("\\(NUM\\)", conNum));
                    jourPubNum = jourPubNum.substring(0, jourPubNum.indexOf(" "));
                    journals.put(jourName, jourPubNum);
                }
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            start = start + numJourPerPage;
            end = end + numJourPerPage;
        }
        return journals;
    }

    /**
     * TO get list of publication title
     * @param authorId : Author ID
     * @param numPub : Number of publication
     * @return : list of title publication
     */
    public static ArrayList getPublicationFromAuthorID(int authorId,int numPub) {
        ArrayList publications = new ArrayList();
        int start = 1;
        int end = MASearchCrawlPatterns.MAX_NUMBER_SHOW_IN_PAGE;
        int numPubPerPage = MASearchCrawlPatterns.MAX_NUMBER_SHOW_IN_PAGE;
        int numPage = (numPub) /numPubPerPage;
        for (int i = 0; i <= numPage; i++) {
            int MaxRunPerPage = numPubPerPage;
            if (i == numPage) {
                MaxRunPerPage = numPub - numPubPerPage * numPage;
            }
            try {
                String htmlContent = CommonURLQuery.getHTMLPageContentWithUTF8( new URL(
                                	MASearchCrawlPatterns.ACCADEMIC_PUBLICATION_QUERY + authorId +
                                	MASearchCrawlPatterns.AND +
                                	MASearchCrawlPatterns.START + "=" + start +
                                	MASearchCrawlPatterns.AND +
                                	MASearchCrawlPatterns.END + "=" + end));

                for (int j = 0; j < MaxRunPerPage; j++) {
                    String conNum = String.valueOf(j);
                    if (j < 10) {
                        conNum = "0" + conNum;
                    }
                    
                    String publicationTitle = CommonHTMLProcessor.getTextOfDivTag(htmlContent,
                                    			MASearchCrawlPatterns.PUBLICATION_PATTERN_DIV.replaceAll(
                                                    "\\(NUM\\)", conNum));
                    publications.add(publicationTitle);
                }
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            start = start + numPubPerPage;
            end = end + numPubPerPage;
        }
        return publications;
    }

    /**
     *
     * @param authorId : Author ID
     * @param numKey : number of Keywords
     * @return list of Keyword
     */
    public static ArrayList getKeyWordFromAuthorID(int authorId,int numKey) {
        ArrayList keywords = new ArrayList();
        int start = 1;
        int end = MASearchCrawlPatterns.MAX_NUMBER_SHOW_IN_PAGE;
        int numKeyPerPage = MASearchCrawlPatterns.MAX_NUMBER_SHOW_IN_PAGE;
        int numPage = (numKey) /numKeyPerPage;
        for (int i = 0; i <= numPage; i++) {
            int MaxRunPerPage = numKeyPerPage;
            if (i == numPage) {
                    MaxRunPerPage = numKey - numKeyPerPage * numPage;
            }
            try {
                String temp = null;
                String keyword = null;
                temp = CommonURLQuery.getHTMLPageContent(new URL(
                                MASearchCrawlPatterns.ACCADEMIC_KEYWORD_QUERY + authorId +
                                MASearchCrawlPatterns.AND +
                                MASearchCrawlPatterns.START + "=" + start +
                                MASearchCrawlPatterns.AND +
                                MASearchCrawlPatterns.END + "=" + end));
                for (int j = 0; j < MaxRunPerPage; j++) {
                    // try getting journal name from pattern tag id
                    String conNum = String.valueOf(j);
                    if (j < 10) {
                            conNum = "0" + conNum;
                    }
                    keyword = CommonHTMLProcessor.getTextOfDivTag(temp,
                                    MASearchCrawlPatterns.CONFERENCE_AND_JOURNAL_AND_KEYWORD_PATTERN_DIV.replaceAll(
                                                    "\\(NUM\\)", conNum));
                    keyword.trim();
                    keywords.add(keyword);
                }
            } catch (MalformedURLException e) {
                    e.printStackTrace();
            } catch (IOException e) {
                    e.printStackTrace();
            }
            start = start + numKeyPerPage;
            end = end + numKeyPerPage;
        }
        return keywords;
    }


}
